﻿using CoachingOrganizer.Logic.Models.Tools.MoneyCalculation;
using CoachingOrganizer.WinPhone.UITools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoachingOrganizer.WinPhone.ViewModels.Tools.MoneyCalculation
{
    public class ReportViewModel : ViewModelBase
    {
        private readonly ReportModel _model;
        private PeriodReportViewModel _currentPeriodReport;
        private PeriodReportViewModel[] _periodReports;
        private PeriodGroupReportViewModel[] _reportItems;
        private decimal? _totalIncomes;
        private decimal? _totalSpents;

        public PeriodReportViewModel CurrentPeriodReport
        {
            get { return _currentPeriodReport; }
            set
            {
                if (_currentPeriodReport != value)
                {
                    _currentPeriodReport = value;
                    if (value != null)
                        _model.CurrentPeriodReport = value.Model;
                }
            }
        }

        public PeriodReportViewModel[] PeriodReports
        {
            get { return _periodReports; }
        }

        public PeriodGroupReportViewModel[] ReportItems
        {
            get { return _reportItems; }
        }

        public int PeriodSizeIndex
        {
            get { return PeriodSizeToIndex(_model.CurrentReportPeriodSize); }
            set { SetPeriodSizeFromIndex(value); }
        }

        public string TotalIncomes
        {
            get { return _totalIncomes.HasValue ? _totalIncomes.Value.ToString("0.##") : string.Empty; }
        }

        public string TotalSpents
        {
            get { return _totalSpents.HasValue ? _totalSpents.Value.ToString("0.##") : string.Empty; }
        }

        public string TotalSummary
        {
            get { return _totalIncomes.HasValue && _totalSpents.HasValue ? (_totalIncomes.Value - _totalSpents.Value).ToString("0.##") : string.Empty; }
        }

        public ReportViewModel(ReportModel model)
        {
            _model = model;
            model.CurrentReportPeriodSizeChanged += Model_CurrentReportPeriodSizeChanged;
            model.CurrentPeriodReportChanged += Model_CurrentPeriodReportChanged;
            UpdatePeriodReports();
        }

        private void UpdatePeriodReports()
        {
            IEnumerable<PeriodReportModel> models = _model.PeriodReports;
            _periodReports = models == null ? null : models.Select(m => new PeriodReportViewModel(m)).ToArray();
            OnPropertyChanged(() => PeriodReports);
        }

        private void UpdateReportItems()
        {
            PeriodReportModel period = _model.CurrentPeriodReport;
            if (period != null)
            {
                _reportItems = period.EnumerateIncomesGroups().Union(period.EnumerateSpentsGroups()).Select(m => new PeriodGroupReportViewModel(m)).ToArray();
                OnPropertyChanged(() => ReportItems);
                _totalIncomes = period.GetTotalIncomes();
                _totalSpents = period.GetTotalSpents();
                OnPropertyChanged(() => TotalIncomes);
                OnPropertyChanged(() => TotalSpents);
                OnPropertyChanged(() => TotalSummary);
            }
        }

        private int PeriodSizeToIndex(TimeSpan timeSpan)
        {
            if (timeSpan == TimeSpan.FromDays(1.0))
                return 0;
            else if (timeSpan == TimeSpan.FromDays(7.0))
                return 1;
            else if (timeSpan == TimeSpan.FromDays(StableMoneyFlowItemModel.AsDaysInMonth))
                return 2;
            else if (timeSpan == TimeSpan.FromDays(StableMoneyFlowItemModel.AsDaysInYear))
                return 3;
            else
                throw new NotImplementedException();
        }

        private void SetPeriodSizeFromIndex(int index)
        {
            switch (index)
            {
                case 0:
                    _model.CurrentReportPeriodSize = TimeSpan.FromDays(1.0);
                    break;
                case 1:
                    _model.CurrentReportPeriodSize = TimeSpan.FromDays(7.0);
                    break;
                case 2:
                    _model.CurrentReportPeriodSize = TimeSpan.FromDays(StableMoneyFlowItemModel.AsDaysInMonth);
                    break;
                case 3:
                    _model.CurrentReportPeriodSize = TimeSpan.FromDays(StableMoneyFlowItemModel.AsDaysInYear);
                    break;
                default:
                    throw new NotImplementedException();
                    break;
            }
        }

        private void Model_CurrentReportPeriodSizeChanged(object sender, EventArgs e)
        {
            UpdatePeriodReports();
        }

        private void Model_CurrentPeriodReportChanged(object sender, EventArgs e)
        {
            UpdateReportItems();
        }
    }
}
